
package com.scs.application.modules.doc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.ObjectMetadata;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Maps;
import com.scs.application.core.aliyun.oss.handler.AliyunOssHandler;
import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.BeanUtils;
import com.scs.application.core.utils.FileUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.modules.doc.dto.FileUploadDTO;
import com.scs.application.modules.doc.entity.FileInfo;
import com.scs.application.modules.doc.entity.FileUpload;
import com.scs.application.modules.doc.mapper.FileInfoMapper;
import com.scs.application.modules.doc.request.FileInfoQueryRequest;
import com.scs.application.modules.doc.service.FileInfoService;
import com.scs.application.modules.doc.service.FileUploadService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 文件 service 实现
 */
@AllArgsConstructor
@Slf4j
@Service
public class FileInfoServiceImpl extends BaseServiceImpl<FileInfoMapper, FileInfo> implements FileInfoService {

    private final AliyunOssHandler aliyunOssHandler;

    private final FileUploadService fileUploadService;

    @Override
    public List<FileInfo> list(FileInfoQueryRequest request) {
        List<FileInfo> list = this.list(Wrappers.<FileInfo>query()
                .eq(StringUtils.isNotBlank(request.getMd5()), "md5", request.getMd5())
                .orderByDesc("gmt_modified")
        );
        return list;
    }

    @Override
    public IPage<FileInfo> page(FileInfoQueryRequest request) {
        IPage page = this.page(request.getPage(), Wrappers.<FileInfo>query()
                .eq(StringUtils.isNotBlank(request.getMd5()), "md5", request.getMd5())
                .orderByDesc("gmt_modified")
        );
        return page;
    }

    @Override
    public FileInfo uploadFile(FileUploadDTO dto) {
        MultipartFile file = dto.getFile();
        String bizType = dto.getBizType();
        String bizKey = dto.getBizKey();

        String fileMd5 = null;
        try {
            fileMd5 = BinaryUtil.encodeMD5(file.getBytes());
        } catch (IOException e) {
            log.error("文件上传失败", e);
            return null;
        }
        // 判断文件MD5是否已存在
        FileInfo fileInfo = this.getOne(
                Wrappers.<FileInfo>query().eq("md5", fileMd5).last("limit 1")
        );
        String extName = "";

        String originalFilename = file.getOriginalFilename();

        if (originalFilename.indexOf(".") != -1) {
            extName = StringUtils.substring(originalFilename, originalFilename.lastIndexOf(".") + 1);
        }

        JSONObject meta = new JSONObject();

        ObjectMetadata metadata = new ObjectMetadata();

        if (StringUtils.isNotBlank(dto.getTags())) {
            JSONObject tags = JSON.parseObject(dto.getTags());
            try {
                meta.put("tags", tags);

                Map<String, String> tagsMap = Maps.newHashMap();

                Map<String, Object> innerMap = tags.getInnerMap();
                for (String key : innerMap.keySet()) {
                    Object objValue = innerMap.get(key);
                    tagsMap.put(key, objValue != null ? objValue.toString() : "");
                }
                metadata.setObjectTagging(tagsMap);
            } catch (Exception e) {
                log.error("JSON转换失败", e);
            }

        }

        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String fileName = uuid + (StringUtils.isBlank(extName) ? "" : ("." + extName));

//        try {
//            aliyunOssHandler.inputStreamUpload(file.getInputStream(), dir, fileName, metadata);
//        } catch (IOException e) {
//            return null;
//        }

        fileInfo = new FileInfo();
        fileInfo.setMd5(fileMd5)
                .setName(fileName)
                .setContentType(file.getContentType()).setPath(resPath + fileName)
                .setSize(file.getSize())
                .setExtensionType(extName)
                .setMetaInfo(meta);

        this.saveCascadeById(fileInfo);
        BufferedOutputStream stream = null;
        try {
            FileUtils.mkdirs(resPath);

            byte[] bytes = file.getBytes();
            stream = new BufferedOutputStream(new FileOutputStream(
                    new File(fileInfo.getPath())));//设置文件路径及名字
            stream.write(bytes);// 写入
            stream.close();
        } catch (Exception e) {
            throw new BusinessException("文件上传失败");
        }

        addFileUpload(fileInfo, bizType, bizKey);

        return fileInfo;
    }

    private void addFileUpload(FileInfo info, String bizType, String bizKey) {
        if (info == null) {
            return;
        }
        FileUpload upload = new FileUpload();

        BeanUtils.copyProperties(info, upload);
        upload.setFileId(info.getId()).setBizType(bizType).setBizKey(bizKey).setId(null);
        fileUploadService.save(upload);
    }
}
